package com.yanghui.aop;


import com.yanghui.annotation.SystemLog;
import com.yanghui.pojo.Log;
import com.yanghui.service.LogService;
import com.yanghui.utils.UserIpUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Component
public class SystemLogAspect {
    @Autowired
    private LogService logService;

    /**
     * Service 层切点
     */
    @Pointcut("@annotation(com.yanghui.annotation.SystemLog)")
    public void serviceAspect() { }

    @After("serviceAspect()")
    public void doServiceLog(JoinPoint joinPoint) {
        HttpServletRequest request =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        Log log = new Log();
        log.setUserType(getUserType(joinPoint));
        log.setIp(UserIpUtil.getIp(request));
        log.setParam(joinPoint.getArgs()[0].toString());
        log.setDescription(getDescription(joinPoint));
        log.setAddTime(new Date());
        System.out.println(log);

        if ("none".equals(log.getParam()) != true) {
            int count = logService.insertLog(log);
        }
    }

    /**
     * 获取注解中对方法的描述信息 用于service层注解
     * @param joinPoint 切点
     * @return 方法描述
     */
    public static String getDescription(JoinPoint joinPoint) {
        String description = "";

        try {
            String targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Object[] args = joinPoint.getArgs();
            Class<?> targetClass = Class.forName(targetName);
            Method[] methods = targetClass.getDeclaredMethods();

            for (Method method : methods) {
                if (method.getName().equals(methodName) == true) {
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    if (parameterTypes.length == args.length) {
                        description = method.getAnnotation(SystemLog.class).description();
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return description;
    }

    /**
     * 获取注解中的用户信息 用于service层注解
     * @param joinPoint 切点
     * @return 方法描述
     */
    public static String getUserType(JoinPoint joinPoint) {
        String userType = "";

        String targetName = null;
        try {
            targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Object[] args = joinPoint.getArgs();
            Class<?> targetClass = Class.forName(targetName);
            Method[] methods = targetClass.getDeclaredMethods();

            for (Method method : methods) {
                if (method.getName().equals(methodName) == true) {
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    if (args.length == parameterTypes.length) {
                        userType = method.getAnnotation(SystemLog.class).userType();
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return userType;
    }
}
